package org.practice.dao;


import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.practice.model.User;
import org.practice.util.MD5Util;
import org.practice.util.UUIDUtil;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
/**
 * @author jack
 */
@Repository(value="userDao")
public class UserDaoImpl extends HibernateTemplate implements UserDao{
	private static Logger logger=Logger.getLogger(UserDaoImpl.class);
	private SessionFactory sessionFactory;
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	//继承自HibernateDaoSupport，set方法被final修饰，不能使用注解
	@Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	public Object templateQuery(StringBuffer query,final Map<String, Object> values){
		final String queryString = query.toString();
		return (Object)this.execute(new HibernateCallback(){
			//Spring管理Session,没有加事务控制，Spring 根据autoCommit=true,在关闭session时提交事务
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				//session.createSQLQuery("sql");//SQL查询
				Query hibernateQuery = session.createQuery(queryString);//HQL查询
				for (String key : values.keySet()) {
					Object value = values.get(key);
					if (value instanceof Collection) {
						hibernateQuery.setParameterList(key, (Collection) value);
					} else if (value instanceof Object[]) {
						hibernateQuery.setParameterList(key, (Object[]) value);
					} else {
						hibernateQuery.setParameter(key, value);
					}
				}
				Object result = hibernateQuery.uniqueResult();
				return result;
			}
			
		});
	}
	
	public User validateUser(final String email, final String password) {
		StringBuffer hql=new StringBuffer("from User u where u.email=:email and u.password=:password");
		Map<String,Object> values=new HashMap<String,Object>();
		values.put("email", email);
		values.put("password", MD5Util.md5(password));
		return (User)templateQuery(hql,values);
	}
	
	public void addUser(User user){
		/*
		 * sessionFactory.getCurrentSession(),从Spring IOC容器中获得当前线程所绑定的一个事务控制的Session,如果该session没有事务，则报错如下所述。
		 * No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
		 * 使不使用模板都是一样的，都没有事务，事务的实现依赖AOP，但模板会自动获得session（如果service方法上没有事务，就通过openSession()得到无事务新session,
		 * 如果就service方法上加了事务声明，就通过getCurrentSession来得到开始事务的session
		 */
		//加入事务控制,则自己不用写try..catch..finally，Spring会自动加入事务控制的切面(自动加入try..catch块)
		user.setPassword(MD5Util.md5(user.getPassword()));
		user.setIntegral(0);
		user.setVerify(false);
		user.setVerifyCode(UUIDUtil.nextCode());
		this.save(user);
		
		////////////////下面是标准的手动事务管理代码///////////////////////
//		Session s=sessionFactory.openSession();
//		try {
//			s.beginTransaction();
//			s.save(user);
//			s.getTransaction().commit();
//		} catch (HibernateException e) {
//			s.getTransaction().rollback();
//			e.printStackTrace();
//		} finally{
//			s.close();
//		}
	}
	public User verifyUser(Integer id,String code){
		User user=(User)this.get(User.class, id);
		if(user!=null&&code.equals(user.getVerifyCode())){
			user.setVerify(true);
			return user;
		}
		return null;
	}
	
	public User findUserById(Integer userId){
		User user = (User) this.get(User.class, userId);
		return user;
	}
	
	public void updateUser(User user){
		this.update(user);
	}
	
	public boolean checkEmail(final String email){
		return (Boolean)this.execute(new HibernateCallback(){
			//Spring管理Session,没有加事务控制，Spring 根据autoCommit=true,在关闭session时提交事务
			public Boolean doInHibernate(Session session)
					throws HibernateException, SQLException {
				//session.createSQLQuery("sql");//SQL查询
				Query hibernateQuery = session.createQuery("select count(*) from User u where u.email=?");//HQL查询
				hibernateQuery.setString(0, email);
				List<Long> list=hibernateQuery.list();
				if(list.get(0).intValue()>0){
					return true;
				}
				return false;
			}
			
		});
	}
}
